package org.ruoyi.graph2.service.impl;
// Neo4jService.java

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.tika.utils.StringUtils;
import org.neo4j.driver.Driver;
import org.neo4j.driver.Record;
import org.neo4j.driver.Result;
import org.neo4j.driver.Session;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Relationship;
import org.ruoyi.graph2.domain.bo.KnowledgeNodeBo;
import org.springframework.stereotype.Service;

import java.util.*;

import static org.neo4j.driver.Values.parameters;

@Slf4j
@Service
@RequiredArgsConstructor
public class Neo4jService {
	private final Driver driver;

//	public Neo4jService(String uri, String user, String password) {
//		this.driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password));
//	}
//
//	public void close() {
//		driver.close();
//	}

	public void createKnowledgeGraph(List<KnowledgeNodeBo> nodes) {
		try (Session session = driver.session()) {
			// 创建所有节点
			for (KnowledgeNodeBo node : nodes) {
				session.writeTransaction(tx -> {
					String query = "CREATE (n:KnowledgeNode { " +
						"id: $id, " +
						"title: $title, " +
						"content: $content, " +
						"level: $level, " +
						"depth: $depth, " +
						"fullPath: $fullPath, " +
						"graphGroup: $graphGroup" +
						"}) RETURN n";
					tx.run(query, parameters(
						"id", node.getId(),
						"title", node.getTitle(),
						"content", node.getContent(),
						"level", node.getLevel(),
						"depth", node.getDepth(),
						"fullPath", node.getFullPath(),
						"graphGroup", node.getGraphGroup()
					));
					return null;
				});
			}

			// 建立层级关系
			for (KnowledgeNodeBo node : nodes) {
				String parentPath = findParentPath(node.getFullPath());
				if (parentPath != null) {
					session.writeTransaction(tx -> {
						String query = "MATCH (parent:KnowledgeNode {fullPath: $parentPath, graphGroup: $graphGroup}), " +
							"(child:KnowledgeNode {id: $childId, graphGroup: $graphGroup}) " +
							"CREATE (parent)-[:HAS_SUB_TOPIC]->(child)";
						tx.run(query, parameters(
							"parentPath", parentPath,
							"childId", node.getId(),
							"graphGroup", node.getGraphGroup()
						));
						return null;
					});
				}
			}
		}
	}

	public void saveKnowledgeGraph(List<Map> nodes, List<Map> edges, String graphGroup) {
		deleteGraph(graphGroup);

		try (Session session = driver.session()) {
			// 创建所有节点
			for (Map node : nodes) {
				session.writeTransaction(tx -> {
					String query = "CREATE (n:KnowledgeNode { " +
						"id: $id, " +
						"title: $title, " +
						"content: $content, " +
						"level: $level, " +
						"depth: $depth, " +
						"fullPath: $fullPath, " +
						"graphGroup: $graphGroup" +
						"}) RETURN n";
					tx.run(query, parameters(
						"id", MapUtils.getString(node, "id"),
						"title", MapUtils.getString(node, "title"),
						"content", MapUtils.getString(node, "content", StringUtils.EMPTY),
						"level", MapUtils.getString(node, "level", StringUtils.EMPTY),
						"depth", MapUtils.getInteger(node, "depth"),
						"fullPath", MapUtils.getString(node, "fullPath", StringUtils.EMPTY),
						"graphGroup", graphGroup
					));
					return null;
				});
			}

			// 建立层级关系
			for (Map edge : edges) {
				session.writeTransaction(tx -> {
					String query = "MATCH (parent:KnowledgeNode {id: $sourceId, graphGroup: $graphGroup}), " +
						"(child:KnowledgeNode {id: $targetId, graphGroup: $graphGroup}) " +
						"CREATE (parent)-[:HAS_SUB_TOPIC]->(child)";
					tx.run(query, parameters(
						"sourceId", MapUtils.getString(edge, "sourceId"),
						"targetId", MapUtils.getString(edge, "targetId"),
						"graphGroup", graphGroup
					));
					return null;
				});
			}
		}
	}

	private String findParentPath(String fullPath) {
		if (!fullPath.contains(".")) return null;

		String[] parts = fullPath.split("\\.");
		if (parts.length <= 1) return null;

		StringBuilder parentPath = new StringBuilder();
		for (int i = 0; i < parts.length - 1; i++) {
			parentPath.append(parts[i]);
			if (i < parts.length - 2) {
				parentPath.append(".");
			}
		}
		parentPath.append(".");

		return parentPath.toString();
	}

	public List<Map> queryVerticesByGraphGroup(String graphGroup, Integer limit) {
		List<Map> vertices = new ArrayList<>();

		try (Session session = driver.session()) {
			String cypher = "MATCH (n {graphGroup: $graphGroup}) " +
				"RETURN n LIMIT $limit";

			Result result = session.run(cypher, parameters(
				"graphGroup", graphGroup,
				"limit", limit
			));

			result.stream().forEach(record -> {
				Node node = record.get("n").asNode();
				vertices.add(node.asMap());
//				vertices.add(nodeToVertex(node));
			});

			log.info("查询到 {} 个节点，知识库ID: {}", vertices.size(), graphGroup);
			return vertices;
		} catch (Exception e) {
			log.error("查询节点失败", e);
			return vertices;
		}
	}

	public List<Map> queryEdgesByGraphGroup(String graphGroup, Integer limit) {
		List<Map> edges = new ArrayList<>();

		try (Session session = driver.session()) {
			// ⭐ 修复：通过节点的 knowledgeId 过滤关系，兼容旧数据
			String cypher = "MATCH (s {graphGroup: $graphGroup})-[r]->(t {graphGroup: $graphGroup}) " +
				"RETURN s, r, t LIMIT $limit";

			log.info("🔍 开始查询关系 - knowledgeId: {}, limit: {}", graphGroup, limit);
			log.debug("执行Cypher: {}", cypher);

			Result result = session.run(cypher, parameters(
				"graphGroup", graphGroup,
				"limit", limit
			));

			int count = 0;
			while (result.hasNext()) {
				Record record = result.next();
				Node source = record.get("s").asNode();
				Relationship rel = record.get("r").asRelationship();
				Node target = record.get("t").asNode();

				// 调试：打印关系详情
				if (count < 3) {  // 只打印前3个
					log.debug("关系#{} - 类型: {}, 起点: {} ({}), 终点: {} ({})",
						count + 1,
						rel.type(),
						source.get("name").asString(),
						source.get("id").asString(),
						target.get("name").asString(),
						target.get("id").asString()
					);
				}

				Map<String, Object> edge = new HashMap<>();
				edge.put("sourceId", source.asMap().get("id"));
				edge.put("targetId", target.asMap().get("id"));
				edges.add(edge);

//				edges.add(relationshipToEdge(source, rel, target));
				count++;
			}

			log.info("✅ 查询到 {} 个关系，graphGroup: {}", edges.size(), graphGroup);
			return edges;
		} catch (Exception e) {
			log.error("❌ 查询关系失败 - graphGroup: {}", graphGroup, e);
			return edges;
		}
	}

	public boolean deleteGraph(String graphGroup) {
		try (Session session = driver.session()) {

			String cypher = "MATCH (n {graphGroup: $graphGroup})-[r]-(n {graphGroup: $graphGroup}) DELETE r;";
			session.run(cypher, parameters("graphGroup", graphGroup));

			cypher = "MATCH (n {graphGroup: $graphGroup}) DETACH DELETE n";

			session.run(cypher, parameters("graphGroup", graphGroup));

			log.info("图谱数据删除成功: graphGroup={}", graphGroup);

			return true;
		} catch (Exception e) {
			log.error("删除图谱数据失败: graphGroup={}", graphGroup, e);
		}
		return false;
	}
}
